/*
Digital Image Processing - Final Project
9 December 2011

Joseph Dombrowski
Josh Dixon
Junmo An
*/

#include <stdio.h>
#include <iostream>
#include "line.h"

using namespace std;

// Constructor
Line::Line(pointD st, pointD en)
{
	start = st;
	end = en;
	if(start.x == end.x)
		vertical = true;
	else
	{
		vertical = false;
		slope = (double)(end.y - start.y)/(double)(end.x - start.x);
	}
	length = sqrt(pow(end.y - start.y,2.0) + pow(end.x - start.x,2.0));
	Yint = start.y - (slope*start.x);

}

// Returns the distance between a point and the closest point on the line
double Line::distFrom(pointD here)
{
	double dist;

	if(slope == 0)
	{
		dist = abs(here.y - start.y);
	}
	else if(vertical)
	{
		dist = abs(start.x - here.x);
	}
	else
	{
		double m1 = slope;
		double m2 = -(1.0/slope);

		double b1 = start.y - (slope * start.x);
		double b2 = here.y - (m2 * here.x);

		double intX = (b2 - b1)/(m1 - m2);
		double intY = m2*intX + b2;

		dist = sqrt(pow(intX - here.x,2.0) + pow(intY - here.y,2.0));
	}

	return dist;
	
}

// Return data about the line
double Line::getSlope()
{
	return slope;
}
double Line::yint()
{
	return Yint;
}
bool Line::Vertical()
{
	return vertical;
}
bool Line::Horizontal()
{
	return slope==0;
}

// Returns x for a given y
double Line::getX(double y)
{
	if(!vertical && slope != 0)
		return (y - Yint)/slope;
	else if(slope == 0 && y == start.y)
		return NULL;
	else
		return start.x;
}

// Returns y for a given x
double Line::getY(double X)
{
	if(!vertical && slope != 0)
		return slope*X + Yint;
	else if(slope == 0)
		return start.y;
	else
		return NULL;
}

// Returns the intersection of two lines, if there is one.
pointD Line::intersect(Line theLine, bool& isIntersect)
{
	double m1 = slope;
	double m2 = theLine.getSlope();
	double intX, intY;
	isIntersect = true;

	if((vertical == true && theLine.Vertical() == true) || m1 == m2)
	{
		isIntersect = false;
		return pointD(0,0);
	}
	else if(vertical == false && theLine.Vertical() == false)
	{
		double b1 = Yint;
		double b2 = theLine.yint();

		intX = (b2 - b1)/(m1 - m2);
		intY = m2*intX + b2;
	}
	else if(vertical)
	{
		double b2 = theLine.yint();

		intX = start.x;
		intY = m2*intX + b2;
	}
	else if(theLine.Vertical())
	{
		double b1 = Yint;

		intX = theLine.getX(0);
		intY = m1*intX + b1;
	}
	return pointD(intX,intY);
}